KENS

Kosinski / Enigma / Nemesis / Saxman Compression and Decompression Libraries
Copyright © 2002-2004 The KENS Project Development Team

1. What is KENS ?
2. Who made KENS ?
3. How do I use KENS in a C/C++ program ?
4. How do I use KENS in a Delphi program ?
5. How do I use KENS in a Visual Basic program ?
6. How do I use KENS in a Game Maker "program" ?
7. What are the functions, and how do I call them ?
8. Advanced topic: How do I decompress to a buffer rather than a file ?

1. What is KENS ?

KENS is a group of four libraries that allow you to compress and decompress data using the Kosinski, Enigma, Nemesis and Saxman compression formats. These libraries, programmed using Visual C++, can be easily used from your applications, even from Visual Basic and Game Maker applications. KENS is being distributed under LGPL. For more info about the LGPL, read LICENSE.HTML.

2. Who made KENS ?

Several people worked on KENS, in a way or another. There are people who cracked the formats, others who wrote the algorithms to compress and decompress the data, some who contributed by making headers allowing to use the libraries easily in other programming languages, and people who tested them heavily and reported bugs. All these people can be considered to be a part of a team, The KENS Project Development Team. Without them, making KENS what it has become today would not have been possible. Here is a list of these people so far (in alphabetical order).

Brett Kosinski | brettk@gpu.srv.ualberta.ca
Damian "Saxman" Grove | saxman@shentel.net
David "Magus" Declerck | ChaosIsLight@aol.com
Korama | amarokorama@msn.com
Roger "Nemesis" Sanders | nemesis2k2hacker@hotmail.com
Stealth | stealth@emulationzone.org
Ultima | ultima@shadowsoft-games.com

3. How do I use KENS in a C/C++ program ?

Include the Kosinski.h, Enigma.h, Nemesis.h or Saxman.h files into any file that calls the compression / decompression routines. Alternatively, you can just include KENS.h, which contains the definitions of all these four files. Then, you have to call KInit, EInit, NInit or SInit before using any of the routines (these functions are used to initialize the pointers to the routines). These functions all take a parameter that specifies the path to the DLL, and they return "true" if initialization worked or "false" if it didn't. It is very important that you check the return value of these functions before calling any of the functions from the DLLs.

4. How do I use KENS in a Delphi program ?

Include the KENS unit into the "uses" clause of any unit that calls the compression / decompression functions. In KENS.pas, there's a compiler switch "KENS_LoadDynamically", which controls whether the KENS DLLs are imported statically (when your program starts up) or dynamically (during runtime of your program). If "KENS_LoadDynamically" is disabled, your program won't load if one of the used KENS DLLs is missing. If "KENS_LoadDynamically" is enabled (default), then you have to call KInit, EInit, NInit or SInit and check the return value before using any of the routines (these functions are used to load the DLLs at runtime and initialize the pointers to the routines). You can also use the helper functions KAvailable, EAvailable, NAvailable and SAvailable, they call the respective Init function if necessary. For an example, please refer to the comments at the begining of KENS.pas.

5. How do I use KENS in a Visual Basic program ?

Simply copy / paste the required declarations at the begining of a module:

Kosinski:
Declare Function KComp Lib "Kosinski.dll" Alias "VBComp" (ByVal Source As Variant, ByVal Destination As Variant, ByVal Moduled As Boolean) As Long
Declare Function KDecomp Lib "Kosinski.dll" Alias "VBDecomp" (ByVal Source As Variant, ByVal Destination As Variant, ByVal Pointer As Long, ByVal Moduled As Boolean) As Long
Declare Function KCompEx Lib "Kosinski.dll" Alias "VBCompEx" (ByVal Source As Variant, ByVal Destination As Variant, ByVal SlideWin As Long, ByVal RecLen As Long, ByVal Moduled As Boolean) As Long

Enigma:
Declare Function EComp Lib "Enigma.dll" Alias "VBComp" (ByVal Source As Variant, ByVal Destination As Variant, ByVal Padding As Boolean) As Long
Declare Function EDecomp Lib "Enigma.dll" Alias "VBDecomp" (ByVal Source As Variant, ByVal Destination As Variant, ByVal Pointer As Long, ByVal Padding As Boolean) As Long

Nemesis:
Declare Function NComp Lib "Nemesis.dll" Alias "VBComp" (ByVal Source As Variant, ByVal Destination As Variant) As Long
Declare Function NDecomp Lib "Nemesis.dll" Alias "VBDecomp" (ByVal Source As Variant, ByVal Destination As Variant, ByVal Pointer As Long) As Long

Saxman:
Declare Function SComp Lib "Saxman.dll" Alias "VBComp2" (ByVal Source As Variant, ByVal Destination As Variant, ByVal WithSize As Boolean) As Long
Declare Function SDecomp Lib "Saxman.dll" Alias "VBDecomp2" (ByVal Source As Variant, ByVal Destination As Variant, ByVal Pointer As Long, ByVal Size As Long) As Long

6. How do I use KENS in a Game Maker "program" ?

Declare the functions as follows:
Kosinski:
external_define('Kosinski.dll', 'GMComp', dll_cdecl, ty_real, 3, ty_string, ty_string, ty_real);
external_define('Kosinski.dll', 'GMDecomp', dll_cdecl, ty_real, 4, ty_string, ty_string, ty_real, ty_real);

Enigma:
external_define('Enigma.dll', 'GMComp', dll_cdecl, ty_real, 3, ty_string, ty_string, ty_real);
external_define('Enigma.dll', 'GMDecomp', dll_cdecl, ty_real, 4, ty_string, ty_string, ty_real, ty_real);

Nemesis:
external_define('Nemesis.dll', 'GMComp', dll_cdecl, ty_real, 2, ty_string, ty_string);
external_define('Nemesis.dll', 'GMDecomp', dll_cdecl, ty_real, 3, ty_string, ty_string, ty_real);

Saxman:
external_define('Saxman.dll', 'GMComp2', dll_cdecl, ty_real, 3, ty_string, ty_string, ty_real);
external_define('Saxman.dll', 'GMDecomp2', dll_cdecl, ty_real, 4, ty_string, ty_string, ty_real, ty_real);

7. What are the functions, and how do I call them ?

Before explaining the functions and their parameters, I will explain the parameters types.
* String: In C/C++, this is represented as char* or char[]. In Delphi, this is represented as PChar. In Visual Basic, this is represented as String. In Game Maker, this is represented as ty_string.
* Long: In C/C++, this is represented as long. In Delphi, this is represented as Longint. In Visual Basic, this is represented as Long. In Game Maker, this type does not exist, but KENS will accept the ty_real type.
* Boolean: In C/C++, this is represented as bool. In Delphi and Visual Basic, this is represented as Boolean. In Game Maker, this type does not exist, but KENS will accept the ty_real type, where 0 means false and anything else (usually 1) means true.

KComp: Compresses data using the Kosinski format
The first parameter is a string representing the source file. The second parameter is a string representing the destination file. The third parameter is a boolean that indicates whether or not to use the Moduled Kosinski compression.

KCompEx: Compresses data using the Kosinski format, and allows to specify a custom Sliding Window and Recurrence Length
The first parameter is a string representing the source file. The second parameter is a string representing the destination file. The third parameter is a long that specifies a custom Sliding Window (default: 8192). The fourth parameter is a long that specifies a custom Recurrence Length (default: 256). The fifth parameter is a boolean that indicates whether or not to use the Moduled Kosinski compression. Due to an internal restriction on the number of parameters, Game Maker can't call this function.

KDecomp: Decompresses data using the Kosinski format
The first parameter is a string representing the source file. The second parameter is a string representing the destination file. The third parameter is a long that indicates the offset to start decompressing from. The fourth parameter is a boolean that indicates whether or not to use the Moduled Kosinski compression.

EComp: Compresses data using the Enigma format
The first parameter is a string representing the source file. The second parameter is a string representing the destination file. The third parameter is a boolean that indicates whether or not to remove the padding when compressing (usually false, as most files you will compress won't have added padding).

EDecomp: Decompresses data using the Enigma format
The first parameter is a string representing the source file. The second parameter is a string representing the destination file. The third parameter is a long that indicates the offset to start decompressing from. The fourth parameter is a boolean that indicates whether or not to add padding when decompressing (usually false, although you might want to add padding for Sonic 1 Special Stages).

NComp: Compresses data using the Nemesis format
The first parameter is a string representing the source file. The second parameter is a string representing the destination file.

NDecomp: Decompresses data using the Nemesis format
The first parameter is a string representing the source file. The second parameter is a string representing the destination file. The third parameter is a long that indicates the offset to start decompressing from.

SComp: Compresses data using the Saxman format
The first parameter is a string representing the source file. The second parameter is a string representing the destination file. The third parameter is a boolean that indicates whether or not to add the size of the compressed file to the output (usually, you will specify true, expect if you're compressing the Sonic 2 Sound Driver).

SDecomp: Decompresses data using the Saxman format
The first parameter is a string representing the source file. The second parameter is a string representing the destination file. The third parameter is a long that indicates the offset to start decompressing from. The fourth parameter is a long that indicates a custom size (specify 0 if you want the decompressor to read the size from the compressed data, otherwise specify a custom size - note that you will only need to specify a custom size when decompressing the Sonic 2 Sound Driver).

8. Advanced topic: How do I decompress to a buffer rather than a file ?

Since version 1.4, it is now possible to decompress data to a buffer rather than a file. However, there is a requirement. You must be using a programming language that is capable of using pointers and calling the standard functions from the DLLs. This means you won't be able to decompress to a buffer under Visual Basic or Game Maker. However, you will be able to do it under C/C++ and Delphi. In order to do so, you will have to use the following functions:
Kosinski: KCompToBuf, KDecompToBuf and KCompExToBuf
Enigma: ECompToBuf and EDecompToBuf
Nemesis: NCompToBuf and NDecompToBuf
Saxman: SCompToBuf and SDecompToBuf
These functions are practically identical to the classic functions. There are only two differences. The second parameter, instead of being a string that contains the name of the destination file, is a pointer to the destination buffer (this pointer being passed by reference). This buffer must be declared as char* or char[] in C/C++ or Pointer in Delphi. Also, right after this parameter, a new parameter was inserted. It is a pointer to a long that will receive the size of the data contained in the buffer. This parameter MUST be specified correctly (don't pass NULL). The rest of the parameters remains unchanged.
Now, here are the two ways of calling these functions.
* If you specify a NULL pointer as the destination buffer (a pointer set to NULL or 0), the function will initialize it by itself and fill the buffer with the output data. The advantage is that the buffer will be initialized to the right size. However you will have to call the FreeBuffer() function from the KENS DLL and pass the pointer to the buffer as a parameter in order to free it. Note that if you are using C++, you may free it by yourself by calling the delete[] operator. Do NOT try to use the ANSI-C free() function on the pointer.
* If you specify an already initialized pointer, the function will simply fill the buffer with the output data. You should ensure that the buffer is large enough to handle the data it will receive, otherwise you'll get an access violation error. You also have to free the pointer by yourself.